/* Bagian 1. ADT System Modus 1 : Load, Save, AddSite, CreateTable */

/* File			: MSystem.c										*/
/* Deskripsi	: realisasi (body) dari MSystem.h				*/
/* Isi			: realisasi / kode program dari semua prototype	*/
/*				  yg didefinisikan pada MSystem.h				*/

/* ADT system */

#include "MSystem.h"
#include "../../Graphics/CGraphics.h"

/* BODY prototype */
	void DestroyNODELIST()
		{
			nodeAddress Q;
			
			while (! ISLINKEDLISTEMPTY(NODELIST))
				{
					Q = FIRST(NODELIST);
					FIRST(NODELIST) = NEXT(Q);
					DeallocateNode(Q);
				}
			NODELIST = CreateEmptyNodeList();
		}
	void DestroyEDGELIST()
		{
			edgeAddress Q;
			
			while (! ISLINKEDLISTEMPTY(EDGELIST))
				{
					Q = FIRST(EDGELIST);
					FIRST(EDGELIST) = NEXT(Q);
					DeallocateEdge(Q);
				}
			EDGELIST = CreateEmptyEdgeList();
		}
	void DestroyTABELMHS()
		{
			AddressMhs QMhs; ownerAddress QOw;
			
			while (CountRecordMhs(TABELMHS) != 0)
				{
					QMhs = FIRST(TABELMHS);
					FIRST(TABELMHS) = QMhs->next;
					while (FIRST(QMhs->_ownerList) != NULL)
						{
							QOw = FIRST(QMhs->_ownerList);
							FIRST(QMhs->_ownerList) = QOw->next;
							DeallocateOwner(QOw);
						}
					(QMhs->_ownerList) = CreateEmptyOwnerList();
					DeallocateRecordMhs(QMhs);
				}
			TABELMHS = CreateEmptyTabelMhs();
		}
	void DestroyTABELMK()
		{
			AddressMK QMK; ownerAddress QOw;
			
			while (CountRecordMK(TABELMK) != 0)
				{
					QMK = FIRST(TABELMK);
					FIRST(TABELMK) = QMK->next;
					while (FIRST(QMK->_ownerList) != NULL)
						{
							QOw = FIRST(QMK->_ownerList);
							FIRST(QMK->_ownerList) = QOw->next;
							DeallocateOwner(QOw);
						}
					(QMK->_ownerList) = CreateEmptyOwnerList();
					DeallocateRecordMK(QMK);
				}
			TABELMK = CreateEmptyTabelMK();
		}
	void DestroyTABELPMK()
		{
			AddressPMK QPMK; ownerAddress QOw;
			
			while (CountRecordPMK(TABELPMK) != 0)
				{
					QPMK = FIRST(TABELPMK);
					FIRST(TABELPMK) = QPMK->next;
					while (FIRST(QPMK->_ownerList) != NULL)
						{
							QOw = FIRST(QPMK->_ownerList);
							FIRST(QPMK->_ownerList) = QOw->next;
							DeallocateOwner(QOw);
						}
					(QPMK->_ownerList) = CreateEmptyOwnerList();
					DeallocateRecordPMK(QPMK);
				}
			TABELPMK = CreateEmptyTabelPMK();
		}
	void DestroyAll()
		{DestroyNODELIST(); DestroyEDGELIST(); DestroyTABELMHS(); DestroyTABELMK(); DestroyTABELPMK();}
	
	void IshLoad(Reader CReader)
		/* Memeriksa apakah command dalam Modus Persiapan yang diketikan adalah Load
		   dengan prekondisi karakter pertama perintah adalah karakter 'L' atau 'l' */
		/* Kesalahan yang dapat ditoleransi adalah hilangnya salah satu huruf atau
		   tertukarnya urutan dua huruf yang berurutan
		   serta adanya penambahan huruf di bagian akhir */
		{
			/* KAMUS LOKAL */
			/* Semua nama yang dipakai dalam BADAN PROSEDUR */
			Load(CharToString("Data/MyInput.in"));
		}
	void Load (string FileName)
		/* Modus Persiapan : Load */
		/* Mengeksekusi semua hal yang dilakukan dalam command Load sesuai dengan spek soal */
		/* Dalam satu tabel yang berada di node yang sama tidak dimungkinkan adanya dua record atau lebih
		   yang memiliki key yang sama */
		/* Dalam satu node yang sama, tidak dimungkinkan adanya dua tabel atau lebih yang memiliki <nama-tabel>
		   yang sama, atau dengan kata lain fragmentasi dan duplikasi diharuskan pada node yang berbeda */
		/* Jika key sama, maka seluruh isi record harus identik */
		/* Kesalahan jumlah argument pada tabel tidak dimungkinkan */
		/* Kesalahan syntax pada tabel tidak dimungkinkan */
		/* @end wajib ada */
		{
			/* KAMUS LOKAL */
				FILE *f;
				int JumlahLokasi;
				bool FatalErr = false, enter = false;
				int RE = 0;
				AddressMhs PMhs = FIRST(TABELMHS);
		
			/* ALGORITMA */
				StartPrintProcess();
				f = fopen(FileName.s, "r");
				ReadArguments(f);
				if (IsStringEqual(CReader.argument[0], CharToString("@nodes")))
					{
						///awal daftar lokasi / simpul
						ContinuePrintProcess(); SetColor(FGI); printf("%s\n", CReader.argument[0].s);
						if (! IsStringInt(CReader.argument[1]))
							{
								ContinuePrintProcess(); SetColor(FYI); printf("%s\n", CReader.argument[1].s);
								StartPrintMsg();
								printf("LOAD ERROR : <jumlah-lokasi> bukan merupakan bilangan bulat\n");
								printf("   FATAL ERROR : is aborted\n");
								FatalErr = true; //halt
							}
						else
							{
								JumlahLokasi = StringToInt(CReader.argument[1]);
								if (JumlahLokasi > 0)
									{
										ContinuePrintProcess(); SetColor(FGI);
										printf("%s\n", CReader.argument[1].s);
										LoadNodes(JumlahLokasi, f, &FatalErr, &RE, &enter);
									}
								else
									{
										ContinuePrintProcess(); SetColor(FYI);
										printf("%s\n", CReader.argument[1].s);
										StartPrintMsg();
										printf("LOAD ERROR : <jumlah-lokasi> tak positif\n");
										printf("   FATAL ERROR : is aborted\n");
										FatalErr = true; //halt
									}
							}
					}
				else
					{
						ContinuePrintProcess(); SetColor(FYI); printf("%s\n", CReader.argument[0].s);
						StartPrintMsg();
						printf("LOAD ERROR : @nodes tidak ditemukan\n");
						printf("   FATAL ERROR : is aborted\n");
						FatalErr = true; //halt
					}
				if (! FatalErr)
					{
						if (! IsStringEqual(CReader.argument[0], CharToString("@end")))
							{
								//@edges
								IshEdges(f, &FatalErr, &enter);
							}
						if (! FatalErr)
							{
								ContinuePrintProcess(); SetColor(FGI); printf("%s\n", CReader.argument[0].s);
								if (RE > 0)
									{
										fclose(f);
										ContinuePrintProcess();
										printf("\n");
										ReLoad(FileName, &FatalErr, &RE);
									}
								if (! FatalErr)
									{
										//update IPK dan SKS
										PMhs = FIRST(TABELMHS);
										while (PMhs != NULL)
											{
												UpdateIPKdanJmlSKSRecordMhs(PMhs, &TABELPMK);
												PMhs = PMhs->next;
											}
										fclose(f);
										ContinuePrintProcess(); printf("\n");
										ContinuePrintProcess(); SetColor(FGI);
										printf("Loading file %s sukses.\n", FileName.s);
										SOURCEFILE = FileName;
									}
							}
					}
				if (FatalErr)
					{
						DestroyAll();
						ContinuePrintProcess(); printf("\n");
						ContinuePrintProcess(); SetColor(FRI); printf("Loading file %s gagal.\n", FileName.s);
					}
		}
	void LoadNodes(int JumlahLokasi, FILE *f, bool *FatalErr, int *RE, bool *enter)
		/* Load @nodes */
		/* Kesalahan syntax CPU Time tidak dimungkinkan, spek bonus */
		{
			/* KAMUS LOKAL */
				int JumlahNode = 0;
				nodeAddress P, Q = FIRST(NODELIST);
				bool Existance = false, AllNil = false, M = false;
				string NamaNode;
				float WaktuRetrieve, WaktuUpdate, WaktuInsert, WaktuDelete;
				bool PunyaClient, PunyaServer, hasTMhs_baru = false, hasTMK_baru = false, hasTPMK_baru = false;
				int i, j;
				char CC;
		
			/* ALGORITMA */
				ReadArguments(f);
				for (i = 1; i <= JumlahLokasi; i++)
					{
						if (CReader.nArgument != 7)
							{
								ContinuePrintProcess(); SetColor(FYI);
								for (j = 0; j < CReader.nArgument; j++)
									{printf("%s ", CReader.argument[j].s);}
								SetColor(FWI); printf("<-|"); //scanf("%c", &CC);
								StartPrintMsg();
								printf("LOAD ERROR : jumlah argument pada <kode-lokasi> tidak tepat\n");
								printf("   MINOR ERROR : is skipped"); *enter = true;
								do
									{
										ReadArguments(f);
										if (! ((CReader.nArgument == 7) || ((IsStringEqual(SubString(											 CReader.argument[0], 0, 1), CharToString("@"))) && (! IsStringEqual(											 SubString(CReader.argument[0], 0, 2), CharToString("@@"))))))
											{
												ContinuePrintProcess(); SetColor(FYI);
												for (j = 0; j < CReader.nArgument; j++)
													{printf("%s ", CReader.argument[j].s);}
												SetColor(FWI); printf("<-|"); 
												StartPrintMsg();
												printf("LOAD ERROR : jumlah argument pada <kode-lokasi> tidak tepat\n");
												printf("   MINOR ERROR : is skipped");
											}
									}
								while (! ((CReader.nArgument == 7) || ((IsStringEqual(SubString(									   CReader.argument[0], 0, 1), CharToString("@"))) && (! IsStringEqual(										  SubString(CReader.argument[0], 0, 2), CharToString("@@"))))));
								//if (CReader.nArgument == 7) {/* do nothing */}
								if (CReader.nArgument == 2)
									{
										if (IsStringEqual(CReader.argument[0], CharToString("@edges")))
											{
												if (JumlahNode == 0)
													{
														ContinuePrintProcess(); SetColor(FYI);
														for (j = 0; j < CReader.nArgument; j++)
															{printf("%s ", CReader.argument[j].s);}
														StartPrintMsg(); printf("LOAD ERROR : @edges dini\n");
														printf("   FATAL ERROR : is aborted\n");
														*FatalErr = true; //halt
														break;
													}
												else if (JumlahNode == 1)
													{
														ContinuePrintProcess(); SetColor(FYI);
														for (j = 0; j < CReader.nArgument; j++)
															{printf("%s ", CReader.argument[j].s);}
														StartPrintMsg();
														printf("LOAD ERROR : komplikasi <jumlah-koneksi>\n");
														printf("   FATAL ERROR : is aborted\n");
														*FatalErr = true; //halt
														break;
													}
												else
													{LoadEdges(f, &(*FatalErr), &(*enter)); break;}
											}
										else
											{
												ContinuePrintProcess(); SetColor(FYI);
												for (j = 0; j < CReader.nArgument; j++)
													{printf("%s ", CReader.argument[j].s);}
												StartPrintMsg();
												printf("LOAD ERROR : komplikasi lokasi @edges\n");
												printf("   FATAL ERROR : is aborted\n");
												*FatalErr = true; //halt
												break;
											}
									}
								else if (CReader.nArgument == 1)	//no more trivial
									{
										if (IsStringEqual(CReader.argument[0], CharToString("@end")))
											{
												ContinuePrintProcess(); SetColor(FYI);
												for (j = 0; j < CReader.nArgument; j++)
													{printf("%s ", CReader.argument[j].s);}
												StartPrintMsg(); printf("LOAD ERROR : @end dini\n");
											}
										else
											{	ContinuePrintProcess(); SetColor(FYI);
												for (j = 0; j < CReader.nArgument; j++)
													{printf("%s ", CReader.argument[j].s);}
												StartPrintMsg(); printf("LOAD ERROR : komplikasi lokasi @end\n");
											}
										printf("   FATAL ERROR : is aborted\n");
										*FatalErr = true; //halt
										break;
									}
								else if (CReader.nArgument != 7) //trivial
									{
										ContinuePrintProcess(); SetColor(FYI);
										for (j = 0; j < CReader.nArgument; j++)
											{printf("%s ", CReader.argument[j].s);}
										StartPrintMsg();
										printf("LOAD ERROR : compicated error\n");
										printf("   FATAL ERROR : is aborted\n");
										*FatalErr = true; //halt
										break;
									}
							}
						else
							{
								JumlahNode++;
								if (! IsStringEqual(SubString(CReader.argument[0], 0, 2), CharToString("@@")))
									{
										ContinuePrintProcess(); SetColor(FYI);
										printf("%s\n", CReader.argument[0].s);
										StartPrintMsg();
										printf("LOAD ERROR : komplikasi @@<kode-lokasi-%d>\n", i);
										printf("   FATAL ERROR : is aborted\n");
										*FatalErr = true; //halt
										break;
									}
								else
									{
										ContinuePrintProcess(); SetColor(FGI);
										printf("%s\n", CReader.argument[0].s);
										NamaNode = DeleteSubString(CReader.argument[0] , 0 , 2);
										if (IsStringEqual(CReader.argument[1], CharToString("Y")))
											{PunyaServer = true;}
										else /* T or else */
											{
												if (! IsStringEqual(CReader.argument[1], CharToString("T")))
													{
														StartPrintMsg();
														printf("LOAD ERROR : status server != Y/T\n");
														printf("   MINOR ERROR : has no server\n");
														SetColor(FYI); M = true;
													}
												PunyaServer = false;
											}
										ContinuePrintProcess(); printf("%s ", CReader.argument[1].s);
										if (! IsStringEqual(CReader.argument[1], CharToString("T")) && 											  ! IsStringEqual(CReader.argument[1], CharToString("Y")))
											{
												SetColor(FWI); printf("<-|"); 
												if (! (! IsStringEqual(CReader.argument[2], CharToString("T")) && 											 		 ! IsStringEqual(CReader.argument[2], CharToString("Y"))))
													{ContinuePrintProcess();}
											}
										SetColor(FGI);
										if (IsStringEqual(CReader.argument[2], CharToString("Y")))
											{PunyaClient = true;}
										else /* T or else */
											{
												if (! IsStringEqual(CReader.argument[2], CharToString("T")))
													{
														StartPrintMsg();
														printf("LOAD ERROR : status client != Y/T\n");
														printf("   MINOR ERROR : has no client\n");
														SetColor(FYI);
														ContinuePrintProcess();
													}
												PunyaClient = false;
											}
										printf("%s ", CReader.argument[2].s);
										if (! IsStringEqual(CReader.argument[2], CharToString("T")) && 											  ! IsStringEqual(CReader.argument[2], CharToString("Y")))
											{
												SetColor(FWI); printf("<-|"); 
												ContinuePrintProcess();
											}
										//kesalahan syntax CPU Time tidak dimungkinkan, spek bonus
										SetColor(FGI);
										for (j = 3; j <= 6; j++)
											{printf("%s ", CReader.argument[j].s);}
										WaktuRetrieve = StringToFloat(CReader.argument[3]);
										WaktuInsert = StringToFloat(CReader.argument[4]);
										WaktuUpdate = StringToFloat(CReader.argument[5]);
										WaktuDelete = StringToFloat(CReader.argument[6]);
										P = AllocateNode(NamaNode, WaktuRetrieve, WaktuUpdate, WaktuInsert,  														WaktuDelete, PunyaClient, PunyaServer);
										if (P == NULL)
											{AllNil = true;}
										if (! AllNil)
											{
												if (! ISLINKEDLISTEMPTY(NODELIST))
													{
														Q = FIRST(NODELIST);
														while (Q != NULL)
															{
																if (IsNodeEqual(P, Q))
																	{Existance = true; break;}
																else
																	{Q = NEXT(Q);}
															}
													}
												if (! Existance)
													{
														AddNode(&NODELIST, P);
														hasTMhs_baru = false; hasTMK_baru = false;
														hasTPMK_baru = false;
														ACTIVENODE = P;
														ReadArguments(f);
														while ((CReader.nArgument == 1) && (! IsStringEqual																  (CReader.argument[0], CharToString("@end"))))
															{
																ChangeTableAvailability(ACTIVENODE, &hasTMhs_baru, 															   &hasTMK_baru, &hasTPMK_baru, f, &(*FatalErr), 															 &(*RE), &(*enter));
																if (*FatalErr == true) {break;}
															}
														//else -> @@kode-lokasi-n+1
													}
												else
													{
														Existance = false;
														SetColor(FWI); printf("<-|");
														StartPrintMsg();
														printf("LOAD ERROR : @@<kode-lokasi-%s> sudah eksis\n", 															  NamaNode.s);
														printf("   MINOR ERROR : is skipped\n");
														DeallocateNode(P);
														do
															{
																ReadArguments(f);
																if (! IsStringEqual(SubString(																	  CReader.argument[0], 0, 1), CharToString("@")))
																		{
																			ContinuePrintProcess(); SetColor(FYI);
																			for (j = 0; j < CReader.nArgument; j++)
																				{printf("%s ", 																						  CReader.argument[j].s);}
																			SetColor(FWI); printf("<-|");
																		}
															}
														while (! IsStringEqual(SubString(CReader.argument[0], 0, 1), CharToString("@")));
														if (! IsStringEqual(SubString(CReader.argument[0], 0, 2), CharToString("@@")))
															{
																if (IsStringEqual(CReader.argument[0], 																	  CharToString("@end")))
																	{
																		StartPrintMsg();
																		printf("LOAD ERROR : complicated ERROR\n");
																		printf("   FATAL ERROR : is aborted\n");
																		*FatalErr = true; //halt
																	}
																else
																	{
																		//@edges
																		IshEdges(f, &(*FatalErr), &(*enter));
																	}
																break;
															}
														//else {/*-> @@kode-lokasi-n+1*/}
													}
											}
										else
											{
												DestroyAll();
												StartPrintMsg();
												printf("LOAD ERROR : not enough memory space\n");
												printf("   FATAL ERROR : is aborted\n");
												*FatalErr = true; //halt
												break;
											}
									}
							}
					}
		}
	void ChangeTableAvailability(nodeAddress P, bool *hasTMhs_baru, bool *hasTMK_baru, bool *hasTPMK_baru,					 			   FILE *f, bool *FatalErr, int *RE, bool *enter)
		/* Mengganti Availability Tabel dari P */
		/* Kesalahan syntax @@<kode-lokasi-n> tidak lagi dimungkinkan */
		/* Kesalahan syntax @ tidak lagi dimungkinkan */
		/* Kesalahan jumlah argumen tidak lagi dimungkinkan */
		/* Duplikasi record PMK tidak dimungkinkan */
		{
			/* KAMUS LOKAL */
				bool XNamaTabel = false, Existance = false, AllNil = false;
				bool kerjaTMhs = false, kerjaTMK = false, kerjaTPMK = false;
				AddressMhs PMhs; AddressMhs QMhs = FIRST(TABELMHS); AddressMK PMk; AddressMK QMk = FIRST(TABELMK);
				ownerAddress POw;
				string NIM, Nama, KotaAsal, Tanggal, DD, MM, YY; date TglLahir;
				string KodeMK, NamaMK, Bidang; int SKS;
				int eRE, lanjuuut, j;
				char CC;
		
			/* ALGORITMA */
				eRE = *RE;
				ContinuePrintProcess(); SetColor(FGI);
				if (IsStringEqual(CReader.argument[0], NAMATABELMHS))
					{*hasTMhs_baru = true; kerjaTMhs = true;}
				else if (IsStringEqual(CReader.argument[0], NAMATABELMK))
					{*hasTMK_baru = true; kerjaTMK = true;}
				else if (IsStringEqual(CReader.argument[0], NAMATABELPMK))
					{*hasTPMK_baru = true; kerjaTPMK = true;}
				else
					{XNamaTabel = true; SetColor(FYI);}
				printf("%s ", CReader.argument[0].s);
				ChangeNodeTableAvailability(P, *hasTMhs_baru, *hasTMK_baru, *hasTPMK_baru);
				ReadArguments(f);
				if (XNamaTabel)
					{
						SetColor(FWI); printf("<-|");
						StartPrintMsg();
						printf("LOAD ERROR : <nama-tabel> tidak valid\n");
						printf("   MINOR ERROR : is skipped\n");
						while (CReader.nArgument != 1 && 
							   (! IsStringEqual(SubString(CReader.argument[0], 0, 1), CharToString("@"))))
							{
								ContinuePrintProcess(); SetColor(FYI);
								for (j = 0; j < CReader.nArgument; j++)
									{printf("%s ", CReader.argument[j].s);}
								SetColor(FWI); printf("<-|");
								ReadArguments(f);
							}
					}
				else
					{printf("\n");}
				//rekurens
				if ((CReader.nArgument == 1) && (! IsStringEqual(CReader.argument[0], CharToString("@end"))))
					{
						//nama-tabel-n+1
						ChangeTableAvailability(ACTIVENODE, &(*hasTMhs_baru), &(*hasTMK_baru), 												  &(*hasTPMK_baru), f, &(*FatalErr), &(*RE), &(*enter));
					}
				else if (! IsStringEqual(SubString(CReader.argument[0], 0, 1), CharToString("@")))
					{
						//isi tabel
						if (kerjaTMhs)
							{
								do
									{
										//data-tabel-Mahasiswa-kolom1s/d6
										NIM = CReader.argument[0];
										Nama = CReader.argument[1];
										if (CReader.argument[2].s[2] == '-')
											{
												DD = SubString(CReader.argument[2], 0, 2);
												lanjuuut = 2;
											}
										else //tanggal hari hanya 1 digit
											{
												DD = SubString(CReader.argument[2], 0, 1);
												lanjuuut = 1;
											}
										Tanggal = StrCat(DD , CharToString("/"));
										if (CReader.argument[2].s[lanjuuut + 3] == '-')
											{
												MM = SubString(CReader.argument[2], (lanjuuut + 1), 2);
												lanjuuut += 3;
											}
										else //tanggal bulan hanya 1 digit
											{
												MM = SubString(CReader.argument[2], (lanjuuut + 1), 1);
												lanjuuut += 2;
											}
										Tanggal = StrCat(Tanggal , MM);
										Tanggal = StrCat(Tanggal , CharToString("/"));
										Tanggal = StrCat(Tanggal , SubString(CReader.argument[2], (lanjuuut + 1), 4));
										TglLahir = StringToDate(Tanggal);
										KotaAsal = CReader.argument[3];
										ContinuePrintProcess(); SetColor(FGI);
										for (j = 0; j < CReader.nArgument; j++)
											{printf("%s ", CReader.argument[j].s);}
										ReadArguments(f);
										PMhs = AllocateRecordMhs(NIM, Nama, TglLahir, KotaAsal);
										if (PMhs == NULL)
											{AllNil = true; break;}
										if (! AllNil)
											{
												if (CountRecordMhs(TABELMHS) != 0)
													{
														QMhs = FIRST(TABELMHS);
														while (QMhs != NULL)
															{
																if (IsRecordMhsEqual(PMhs, QMhs))
																	{Existance = true; break;}
																else
																	{QMhs = QMhs->next;}
															}
													}
												if (! Existance)
													{
														AddRecordMhs(PMhs, &TABELMHS);
														QMhs = PMhs;
													}
												else
													{
														Existance = false;
														DeallocateRecordMhs(PMhs);
													}
												POw = AllocateOwnerList(P);
												AddOwnerToRecordMhs(QMhs, POw);
											}
									}
								while (CReader.nArgument == 6);
							}
						else if (kerjaTMK)
							{
								do
									{
										//data-tabel-MataKuliah-kolom1s/d4
										KodeMK = CReader.argument[0];
										NamaMK = CReader.argument[1];
										SKS = StringToInt(CReader.argument[2]);
										Bidang = CReader.argument[3];
										ContinuePrintProcess(); SetColor(FGI);
										for (j = 0; j < CReader.nArgument; j++)
											{printf("%s ", CReader.argument[j].s);}
										ReadArguments(f);
										PMk = AllocateRecordMK(KodeMK, NamaMK, SKS, Bidang);
										if (PMk == NULL)
											{AllNil = true; break;}
										if (! AllNil)
											{
												if (CountRecordMK(TABELMK) != 0)
													{
														QMk = FIRST(TABELMK);
														while (QMk != NULL)
															{
																if (IsRecordMKEqual(PMk, QMk))
																	{Existance = true; break;}
																else
																	{QMk = QMk->next;}
															}
													}
												if (! Existance)
													{
														AddRecordMK(PMk, &TABELMK);
														QMk = PMk;
													}
												else
													{
														Existance = false;
														DeallocateRecordMK(PMk);
													}
												POw = AllocateOwnerList(P);
												AddOwnerToRecordMK(QMk, POw);
											}
									}
								while (CReader.nArgument == 4);
							}
						else if (kerjaTPMK) /* trivial */
							{
								*RE = ++eRE;
								do
									{ReadArguments(f);}
								while (CReader.nArgument == 5);
							}
						if (AllNil)
						{
							DestroyAll();
							StartPrintMsg();
							printf("LOAD ERROR : not enough memory space\n");
							printf("   FATAL ERROR : is aborted\n");
							*FatalErr = true; //halt
						}
					}
				else if (IsStringEqual(SubString(CReader.argument[0], 0, 1), CharToString("@"))) //trivial
					{
						// if (IsStringEqual(SubString(CReader.argument[0], 0, 2), CharToString("@@"))) //basis
							// {/*@@kode-lokasi-n+1*/}
						if (! IsStringEqual(SubString(CReader.argument[0], 0, 2), CharToString("@@")))
							{
								if (IsStringEqual(CReader.argument[0], CharToString("@edges")))
									{
										//@edges
										LoadEdges(f, &(*FatalErr), &(*enter));
									}
								else if (IsStringEqual(CReader.argument[0], CharToString("@end"))) //trivial
									{
										StartPrintMsg();
										printf("LOAD ERROR : @end dini\n");
										printf("   FATAL ERROR : is aborted\n");
										*FatalErr = true; //halt
									}
							}
					}
		}
	void ReLoad (string FileName, bool *FatalErr, int *RE)
		/* Me-Load ulang TPMK */
		{
			/* KAMUS LOKAL */
				FILE *f;
				Reader PrevReader;
				string NamaNode;
		
			/* ALGORITMA */
				f = fopen(FileName.s, "r");
				ReadArguments(f);
				do
					{
						while (CReader.nArgument != 1)
							{
								PrevReader = CReader;
								ReadArguments(f);
							}
						NamaNode = DeleteSubString(PrevReader.argument[0] , 0 , 2);
						LoadTPMK(f, NamaNode, &(*FatalErr), &(*RE));
						if (*FatalErr == true) {break;}
					}
				while (*RE > 0);
				
		}
	void LoadTPMK(FILE *f, string NamaNode, bool *FatalErr, int *RE)
		/* Mengedit TPML */
		{
			/* KAMUS LOKAL */
				string NamaNextNode;
				Reader PrevReader;
				AddressMhs PMhs; AddressMK PMk; int Semester; ThnAkademik T; char nilai;
				string NIM, KodeMK;
				AddressPMK PPMk; AddressPMK QPMk = FIRST(TABELPMK);
				bool AllNil = false, Existance = false;
				ownerAddress POw;
				int j;
	
			/* ALGORITMA */
				if (IsStringEqual(CReader.argument[0], NAMATABELPMK))
					{
						ContinuePrintProcess(); SetColor(FGI); printf("%s\n", NamaNode.s);
						ContinuePrintProcess(); printf("%s\n", CReader.argument[0].s);
						ReadArguments(f);
						do
							{
								//data-tabel-PengambilanMK-kolom1s/d5
								NIM = CReader.argument[0];
								PMhs = SearchRecordMhsByNIM(NIM, &TABELMHS);
								if (PMhs == NULL)
									{
										ContinuePrintProcess(); SetColor(FYI);
										for (j = 0; j < CReader.nArgument; j++)
											{printf("%s ", CReader.argument[j].s);}
										StartPrintMsg();
										printf("LOAD ERROR : no NIM matched\n");
										printf("   FATAL ERROR : is aborted\n");
										*FatalErr = true; //halt
										break;
									} else {
								KodeMK = CReader.argument[1];
								PMk = SearchRecordMKByKode(KodeMK, &TABELMK);
								if (PMk == NULL)
									{
										ContinuePrintProcess(); SetColor(FYI);
										for (j = 0; j < CReader.nArgument; j++)
											{printf("%s ", CReader.argument[j].s);}
										StartPrintMsg();
										printf("LOAD ERROR : no KodeMK matched\n");
										printf("   FATAL ERROR : is aborted\n");
										*FatalErr = true; //halt
										break;
									} else {
								ContinuePrintProcess(); SetColor(FGI);
								for (j = 0; j < CReader.nArgument; j++)
									{printf("%s ", CReader.argument[j].s);}
								Semester = StringToInt(CReader.argument[2]);
								T = CreateThnAkademik(StringToInt(SubString(CReader.argument[3], 0, 4)), 													  StringToInt(DeleteSubString(CReader.argument[3], 0, 5)));
								nilai = CReader.argument[4].s[0];
								ReadArguments(f);
								PPMk = AllocateRecordPMK(PMhs, PMk, Semester, T, nilai);
								if (PPMk == NULL)
									{AllNil = true;}
								if (! AllNil)
									{
										AddRecordPMK(PPMk, &TABELPMK);
										POw = AllocateOwnerList(SearchNodeByName(&NODELIST, NamaNode));
										AddOwnerToRecordPMK(PPMk, POw);
									}
								else
									{
										DestroyAll();
										StartPrintMsg();
										printf("LOAD ERROR : not enough memory space\n");
										printf("   FATAL ERROR : is aborted\n");
										*FatalErr = true; //halt
										break;
									}
											}}
							}
						while (CReader.nArgument == 5);
						*RE -= *RE;
					}
				else
					{
						do
							{ReadArguments(f);}
						while (CReader.nArgument != 1 &&
							   (! IsStringEqual(SubString(CReader.argument[0], 0, 2), CharToString("@@"))));
						if (CReader.nArgument == 1)
							{LoadTPMK(f, NamaNode, &(*FatalErr), &(*RE));}
						else
							{
								NamaNextNode = DeleteSubString(CReader.argument[0] , 0 , 2);
								ReadArguments(f);
								if (CReader.nArgument == 1)
									{LoadTPMK(f, NamaNextNode, &(*FatalErr), &(*RE));}
								else
									{
										while (CReader.nArgument != 1)
											{
												PrevReader = CReader;
												ReadArguments(f);
											}
										NamaNextNode = DeleteSubString(PrevReader.argument[0] , 0 , 2);
										LoadTPMK(f, NamaNextNode, &(*FatalErr), &(*RE));
									}
							}
					}
		}
	void IshEdges(FILE *f, bool *FatalErr, bool *enter)
		/* Mengecek @edges */
		{
			/* KAMUS LOKAL */
	
			/* ALGORITMA */
				if (IsStringEqual(CReader.argument[0], CharToString("@edges")))
					{
						///akhir daftar lokasi / simpul; awal daftar hubungan antar lokasi / sisi
						ContinuePrintProcess(); SetColor(FGI); printf("%s\n", CReader.argument[0].s);
						LoadEdges(f, &(*FatalErr), &(*enter));
					}
				else
					{
						ContinuePrintProcess(); SetColor(FYI); printf("%s\n", CReader.argument[0].s);
						StartPrintMsg();
						printf("LOAD ERROR : @edges tidak ditemukan\n");
						printf("   FATAL ERROR : is aborted\n");
						*FatalErr = true; //halt
					}
		}
	void LoadEdges(FILE *f, bool *FatalErr, bool *enter)
		/* Load @edges */
		{
			/* KAMUS LOKAL */
				int JumlahKoneksi, i, j;
				string KodeLokasi1, KodeLokasi2;
				nodeAddress A, B;
				edgeAddress Q;
				float uploadSpeed, downloadSpeed;
				bool AllNil = false;
	
			/* ALGORITMA */
				if (! IsStringInt(CReader.argument[1]))
					{
						ContinuePrintProcess(); SetColor(FYI); printf("%s\n", CReader.argument[1].s);
						StartPrintMsg();
						printf("LOAD ERROR : <jumlah-koneksi> bukan merupakan bilangan bulat\n");
						printf("   FATAL ERROR : is aborted\n");
						*FatalErr = true; //halt
					}
				else
					{
						JumlahKoneksi = StringToInt(CReader.argument[1]);
						if (JumlahKoneksi > 0)
							{
								ContinuePrintProcess(); SetColor(FGI); printf("%s\n", CReader.argument[1].s);
								ReadArguments(f);
								for (i = 1; i <= JumlahKoneksi; i++)
									{
										if (CReader.nArgument != 4 &&
											(! IsStringEqual(CReader.argument[0], CharToString("@end"))))
											{
												ContinuePrintProcess(); SetColor(FYI);
												for (j = 0; j < CReader.nArgument; j++)
													{printf("%s ", CReader.argument[j].s);}
												SetColor(FWI); printf("<-|");
												StartPrintMsg();
												printf("LOAD ERROR : jumlah argument tidak tepat\n");
												printf("   MINOR ERROR : is skipped\n");
												do
													{
														ReadArguments(f);
														if (CReader.nArgument != 4 && CReader.nArgument != 1)
															{
																ContinuePrintProcess(); SetColor(FYI);
																for (j = 0; j < CReader.nArgument; j++)
																	{printf("%s ", CReader.argument[j].s);}
																SetColor(FWI); printf("<-|"); 
															}
													}
												while (CReader.nArgument != 4 && CReader.nArgument != 1);
											}
										else if (CReader.nArgument == 4)
											{
												//do sumthing
												KodeLokasi1 = CReader.argument[0];
												A = SearchNodeByName(&NODELIST, KodeLokasi1);
												KodeLokasi2 = CReader.argument[1];
												B = SearchNodeByName(&NODELIST, KodeLokasi2);
												if (A != NULL && B != NULL)
													{
														if (IsStringFloat(CReader.argument[2]) &&															 IsStringFloat(CReader.argument[3]))
															{
																ContinuePrintProcess(); SetColor(FGI);
																for (j = 0; j < CReader.nArgument; j++)
																	{printf("%s ", CReader.argument[j].s);}
																uploadSpeed = StringToFloat(CReader.argument[2]);
																downloadSpeed = StringToFloat(CReader.argument[3]);
																Q = AllocateEdge(A, B, uploadSpeed, downloadSpeed);
																if (Q == NULL)
																	{AllNil = true;}
																if (! AllNil)
																	{
																		AddEdge(&EDGELIST, Q);
																	}
																else
																	{
																		DestroyAll();
																		StartPrintMsg();
																		printf("LOAD ERROR : not enough memory space\n");
																		printf("   FATAL ERROR : is aborted\n");
																		*FatalErr = true; //halt
																		break;
																	}
															}
														else
															{
																ContinuePrintProcess(); SetColor(FYI);
																for (j = 0; j < CReader.nArgument; j++)
																	{printf("%s ", CReader.argument[j].s);}
																SetColor(FWI); printf("<-|");
																StartPrintMsg();
																printf("LOAD ERROR : speed tidak valid\n");
																printf("   MINOR ERROR : is skipped\n");
															}
													}
												else
													{
														ContinuePrintProcess(); SetColor(FYI);
														for (j = 0; j < CReader.nArgument; j++)
															{printf("%s ", CReader.argument[j].s);}
														SetColor(FWI); printf("<-|");
														StartPrintMsg();
														printf("LOAD ERROR : <kode-lokasi> tidak eksis\n");
														printf("   MINOR ERROR : is skipped\n");
													}
												ReadArguments(f);
											}
									}
							}
						else
							{
								ContinuePrintProcess(); SetColor(FYI); printf("%s\n", CReader.argument[1].s);
								StartPrintMsg();
								printf("LOAD ERROR : <jumlah-koneksi> tak positif\n");
								printf("   FATAL ERROR : is aborted\n");
								*FatalErr = true; //halt
							}
					}
		}
